package com.celesea.sso.user.service;

import com.celesea.framework.authority.*;
import com.celesea.framework.util.CollectionKit;
import com.celesea.sso.user.dao.UserDao;
import com.celesea.sso.user.entity.User;
import com.celesea.sso.user.vo.LoginVo;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * @author JackYuan
 * @create 2017-11-08 21:12
 */
@Service
public class UserServiceImpl implements UserService {

    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private UserDao userDao;

    @Override
    public AuthorityPrincipal selectLogin(LoginVo loginVo) {
        AuthorityPrincipal principal = new AuthorityPrincipal();
        principal.setUpdateTime(System.currentTimeMillis());
        User user = selectByUserName(loginVo);
        principal.setUsername(user.getAccount());
        principal.setPassword(user.getPassword());
        principal.setTenant(selectTenant(user));
        initAuthorities(principal,user);
        // 生成一个uuid的loginSessionId
        principal.setLoginSessionId(UUID.randomUUID().toString());
        principal.setUser(coverUser(user));
        principal.setDept(coverDept(user));
        return principal;
    }

    private void initAuthorities(AuthorityPrincipal principal, User user){
        Set<AuthorityGroup> groups=selectGroups(user);
        principal.setGroups(groups);
        Set<AuthorityRole> roles=selectRoles(user);
        principal.setRoles(roles);
        Set<AuthorityPoint> points=selectPoint(user);
        if(CollectionKit.isNotEmpty(roles)){
            roles.forEach(item->{
                points.add(new AuthorityPoint(item.getCode()));
            });
        }
        principal.setPoints(points);
    }

    private Dept coverDept(User user) {
        Dept dept = new Dept();
        Assert.notNull(user.getCompany(),"用户没有所属公司信息！");
        dept.setId(user.getDeptId());
        dept.setName(user.getDeptName());
        dept.setCompany(user.getCompany());
        return dept;
    }

    private com.celesea.framework.authority.User coverUser(User user) {
        com.celesea.framework.authority.User detail = new com.celesea.framework.authority.User();
        detail.setId(user.getId());
        detail.setName(user.getName());
        detail.setAccount(user.getAccount());
        detail.setPassword(user.getPassword());
        return detail;
    }

    private Tenant selectTenant(User user) {
        Tenant tenant = new Tenant();
        tenant.setId(user.getTenantId());
        return tenant;
    }


    private Set<AuthorityPoint> selectPoint(User user) {
        return Sets.newHashSet(userDao.selectUserOfPoints(user));
    }

    private Set<AuthorityRole> selectRoles(User user) {
        return Sets.newHashSet(userDao.selectUserOfRoles(user));
    }

    private Set<AuthorityGroup> selectGroups(User user) {
        return Sets.newHashSet(userDao.selectUserOfGroups(user));
    }

    private User selectByUserName(LoginVo loginVo) {
        Example example = new Example(User.class);
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andEqualTo("account", loginVo.getUsername());
        criteria1.andEqualTo("password", loginVo.getPassword());
        List<User> users = userDao.selectByExample(example);
        if (CollectionUtils.isEmpty(users)) {
            logger.error("登录信息：{}错误", loginVo);
            throw new RuntimeException("用户名或密码错误！");
        }
        return users.get(0);
    }
}
